<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- saved from url=(0062)http://java.dzone.com/articles/static-groovy-and-concurrency-3 -->
<HTML xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" class="js"><HEAD><META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Static Groovy and Concurrency: Type Inference in Action | Javalobby</TITLE>

<LINK rel="alternate" type="application/rss+xml" title="Comments for &quot;Static Groovy and Concurrency: Type Inference in Action&quot;" href="http://java.dzone.com/crss/node/14831">

<LINK rel="shortcut icon" href="http://java.dzone.com/misc/favicon.ico" type="image/x-icon">
	<LINK rel="alternate" type="application/rss+xml" title="Javalobby RSS" href="http://feeds.dzone.com/javalobby/frontpage">
	<LINK type="text/css" rel="stylesheet" media="all" href="./_files/cf98709b5a62f306d8bd2df2ba0b7564.css">
<LINK type="text/css" rel="stylesheet" media="print" href="./_files/4050910e305418353c70d479dbbedb5a.css">
			<META name="Description" content="My previous article on static compilation of Groovy  describes the idea of combining the expressiveness of Groovy with static type-checking to achieve the...">
		
</HEAD><BODY class="sidebar-right">

<DIV id="header-region" class="clear-block"></DIV>

<DIV id="wrapper" class="fewerAds">
<DIV id="container" class="clear-block">
	<DIV id="header">
		<DIV id="masthead">
			<DIV class="join">
			  																<IMG src="./_files/picture-280906.png" alt="" title="" class="mh_avatar" width="64" height="64">								<A href="http://java.dzone.com/users/jackhung-0">jack_hung</A><BR>
								<A href="http://java.dzone.com/privatemsg">Unread: 0</A><BR>
				<A href="http://java.dzone.com/node/add">Post content</A><BR>
				<A href="http://java.dzone.com/user/280906/edit/Site+Preferences">Want less ads?</A><BR>
				<A href="http://java.dzone.com/logout" title="Log out">Log out</A>
							</DIV>
			<DIV id="site_id">
				<A href="http://www.dzone.com/" title="DZone: Your Personal Tech Universe"><IMG class="dz_logo" src="./_files/mh_dzone_logo.gif" alt="DZone: Your Personal Tech Universe" title="DZone: Your Personal Tech Universe"></A>
				<A href="http://java.dzone.com/" title="Javalobby"><IMG class="site_logo" src="./_files/mh_logo_java.gif" alt="Javalobby" title="Javalobby"></A>
				<SPAN class="site_slogan">The heart of the Java developer community</SPAN>
			</DIV>
			<DIV class="global_menu">
								<UL class="nice-menu nice-menu-down" id="nice-menu-1"><LI id="menu-211" class="menu-path-front"><A href="http://java.dzone.com/">Home</A></LI>
<LI id="menu-125" class="menuparent menu-path-domain"><A href="http://java.dzone.com/domain">Zones</A><UL><LI id="menu-295" class="menu-path-domain-dotnet.dzone.com"><A href="http://java.dzone.com/domain/dotnet.dzone.com">.NET Zone</A></LI>
<LI id="menu-358" class="menu-path-domain-agile.dzone.com"><A href="http://java.dzone.com/domain/agile.dzone.com" title="Go to agile.dzone.com">Agile Zone</A></LI>
<LI id="menu-189" class="menu-path-domain-architects.dzone.com"><A href="http://java.dzone.com/domain/architects.dzone.com" title="Go to architects.dzone.com">Architects Zone</A></LI>
<LI id="menu-400" class="menu-path-domain-books.dzone.com"><A href="http://java.dzone.com/domain/books.dzone.com" title="Go to books.dzone.com">Book Zone</A></LI>
<LI id="menu-3197" class="menu-path-domain-reach.dzone.com"><A href="http://java.dzone.com/domain/reach.dzone.com" title="Go to reach.dzone.com">DZone Reach</A></LI>
<LI id="menu-413" class="menu-path-domain-eclipse.dzone.com"><A href="http://java.dzone.com/domain/eclipse.dzone.com" title="Go to eclipse.dzone.com">Eclipse Zone</A></LI>
<LI id="menu-416" class="menu-path-domain-groovy.dzone.com"><A href="http://java.dzone.com/domain/groovy.dzone.com" title="Go to groovy.dzone.com">Groovy Zone</A></LI>
<LI id="menu-426" class="menu-path-domain-java.dzone.com"><A href="http://java.dzone.com/domain/java.dzone.com" title="Go to java.dzone.com">Javalobby</A></LI>
<LI id="menu-317" class="menu-path-domain-jetbrains.dzone.com"><A href="http://java.dzone.com/domain/jetbrains.dzone.com" title="Go to jetbrains.dzone.com">JetBrains Zone</A></LI>
<LI id="menu-431" class="menu-path-domain-netbeans.dzone.com"><A href="http://java.dzone.com/domain/netbeans.dzone.com" title="Go to netbeans.dzone.com">NetBeans Zone</A></LI>
<LI id="menu-433" class="menu-path-domain-php.dzone.com"><A href="http://java.dzone.com/domain/php.dzone.com" title="Go to php.dzone.com">PHP Zone</A></LI>
<LI id="menu-438" class="menu-path-domain-ria.dzone.com"><A href="http://java.dzone.com/domain/ria.dzone.com" title="Go to ria.dzone.com">RIA Zone</A></LI>
<LI id="menu-441" class="menu-path-domain-refcardz.dzone.com"><A href="http://java.dzone.com/domain/refcardz.dzone.com" title="Go to refcardz.dzone.com">Refcardz</A></LI>
<LI id="menu-141" class="menu-path-domain-ruby.dzone.com"><A href="http://java.dzone.com/domain/ruby.dzone.com">Ruby Zone</A></LI>
<LI id="menu-314" class="menu-path-domain-soa.dzone.com"><A href="http://java.dzone.com/domain/soa.dzone.com" title="Go to soa.dzone.com">SOA Zone</A></LI>
<LI id="menu-142" class="menu-path-domain-sql.dzone.com"><A href="http://java.dzone.com/domain/sql.dzone.com">SQL Zone</A></LI>
<LI id="menu-287" class="menu-path-domain-server.dzone.com"><A href="http://java.dzone.com/domain/server.dzone.com">Server Zone</A></LI>
<LI id="menu-454" class="menu-path-domain-css.dzone.com"><A href="http://java.dzone.com/domain/css.dzone.com" title="Go to css.dzone.com">Web Builder Zone</A></LI>
</UL>
</LI>
<LI id="menu-367" class="menu-path-library.dzone.com"><A href="http://library.dzone.com/">Library</A></LI>
<LI id="menu-167" class="menu-path-refcardz.dzone.com-"><A href="http://refcardz.dzone.com/">Refcardz</A></LI>
<LI id="menu-169" class="menu-path-forums.dzone.com"><A href="http://forums.dzone.com/">Forums</A></LI>
<LI id="menu-215" class="menu-path-www.dzone.com-links"><A href="http://www.dzone.com/links">Links</A></LI>
<LI id="menu-1349" class="menu-path-snippets.dzone.com"><A href="http://snippets.dzone.com/" title="">Snippets</A></LI>
</UL>
			</DIV>
				<DIV class="mh_leader">
	<DIV class="leaderboard">
    <!-- BEGIN ADVERTPRO ADVANCED CODE BLOCK -->

      <SCRIPT language="JavaScript" type="text/javascript">
    <!--
    document.write('<SCR'+'IPT src="http://avpa.dzone.com/servlet/view/banner/javascript/zone?zid=95&keywords=java.dzone.com&pid=0&random='+Math.floor(89999999*Math.random()+10000000)+'&millis='+new Date().getTime()+'" language="JavaScript" type="text/javascript"></SCR'+'IPT>');
    //-->
    </SCRIPT>

<SCRIPT src="./_files/zone" language="JavaScript" type="text/javascript"></SCRIPT>

      <NOSCRIPT></NOSCRIPT>
      <!-- END ADVERTPRO ADVANCED CODE BLOCK -->
    </DIV>
    </DIV>
		
		</DIV>
	</DIV>
	<!-- end of header -->
	<DIV id="center"><DIV id="squeeze">
		<DIV id="article"> <DIV class="breadcrumb"><A href="http://java.dzone.com/">Home</A></DIV>						 
						<DIV id="articleHead">
		   <DIV id="dzone_vote_widget" style="float: left; margin-right: 8px;">
		   <SCRIPT type="text/javascript">var dzone_title = 'Static Groovy and Concurrency: Type Inference in Action';</SCRIPT>
			 		   <SCRIPT type="text/javascript">var dzone_url = 'http://groovy.dzone.com/articles/static-groovy-and-concurrency-3';</SCRIPT>
		   <SCRIPT language="javascript" src="./_files/zoneit.js"></SCRIPT><IFRAME src="./_files/zoneit.html" height="70" width="50" scrolling="no" frameborder="0"></IFRAME></DIV>		   <H1>Static Groovy and Concurrency: Type Inference in Action</H1>
														</DIV>
							
			<DIV id="articleText">
						
			
			<DIV id="node-14831" class="node node-page node-article">


  <DIV class="meta"> 
    <SPAN class="submitted">Submitted by Alex Tkachman on Mon, 2009/11/30 - 10:48am</SPAN>
    <DIV class="serviceTags">
    	<DIV class="service-links"><DIV class="item-list"><UL><LI class="first"><A href="http://del.icio.us/post?url=http%3A%2F%2Fgroovy.dzone.com%2Farticles%2Fstatic-groovy-and-concurrency-3&title=Static+Groovy+and+Concurrency%3A+Type+Inference+in+Action" title="Bookmark this post on del.icio.us." rel="nofollow"><IMG src="./_files/delicious.png" alt="Delicious"></A></LI>
<LI class="first"><A href="http://digg.com/submit?phase=2&url=http%3A%2F%2Fgroovy.dzone.com%2Farticles%2Fstatic-groovy-and-concurrency-3&title=Static+Groovy+and+Concurrency%3A+Type+Inference+in+Action" title="Digg this post on digg.com." rel="nofollow"><IMG src="./_files/digg.png" alt="Digg"></A></LI>
<LI class="first"><A href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fgroovy.dzone.com%2Farticles%2Fstatic-groovy-and-concurrency-3&title=Static+Groovy+and+Concurrency%3A+Type+Inference+in+Action" title="Thumb this up at StumbleUpon." rel="nofollow"><IMG src="./_files/stumbleit.png" alt="StumbleUpon"></A></LI>
<LI class="first"><A href="http://reddit.com/submit?url=http%3A%2F%2Fgroovy.dzone.com%2Farticles%2Fstatic-groovy-and-concurrency-3&title=Static+Groovy+and+Concurrency%3A+Type+Inference+in+Action" title="Submit this post on reddit.com." rel="nofollow"><IMG src="./_files/reddit.png" alt="Reddit"></A></LI>
<LI class="first"><A href="http://technorati.com/search/http%3A%2F%2Fgroovy.dzone.com%2Farticles%2Fstatic-groovy-and-concurrency-3" title="Search Technorati for links to this post." rel="nofollow"><IMG src="./_files/technorati.png" alt="Technorati"></A></LI>
</UL></DIV></DIV>        <SPAN class="terms">Tags: <UL class="links inline"><LI class="taxonomy_term_4360 first"><A href="http://java.dzone.com/category/dzone-taxonomy/java" rel="tag" title="">Java</A></LI>
<LI class="taxonomy_term_4420 last"><A href="http://java.dzone.com/category/dzone-taxonomy/groovy" rel="tag" title="">Groovy</A></LI>
</UL></SPAN>
    </DIV>
  </DIV>
 
  <DIV class="content" style="margin-bottom: 5px;">      		<DIV class="related_library_content" style="float: right;"><H3>We Recommend These Resources</H3><H4 style="background: url(/sites/all/modules/dzone/dzone_library/icons/page_external.png) no-repeat 0 0;" class="sponsored_link"><A href="http://java.dzone.com/assets/request/sponsored_link/9223?oid=rel14831">Flex 3 Download Refcard Link</A></H4><H4 style="background: url(/sites/all/modules/dzone/dzone_library/icons/page_external.png) no-repeat 0 0;" class="sponsored_link"><A href="http://java.dzone.com/assets/request/sponsored_link/9645?oid=rel14831">FREE Tutorial - Getting Started with FUSE ESB 4</A></H4><H4 style="background: url(/sites/all/modules/dzone/dzone_library/icons/page_external.png) no-repeat 0 0;" class="sponsored_link"><A href="http://java.dzone.com/assets/request/sponsored_link/11094?oid=rel14831">June 15 Refcard Email Flex 3 Download Link</A></H4><H4 style="background: url(/sites/all/modules/dzone/dzone_library/icons/page_external.png) no-repeat 0 0;" class="sponsored_link"><A href="http://java.dzone.com/assets/request/sponsored_link/10833?oid=rel14831">Flex PHP Article - Flex SDK Download</A></H4><H4 style="background: url(/sites/all/modules/dzone/dzone_library/icons/page_external.png) no-repeat 0 0;" class="sponsored_link"><A href="http://library.dzone.com/assets/request/sponsored_link/11133?oid=rel14831">The Flash Platform At A Glance PDF</A></H4></DIV>		<SPAN class="print-link"></SPAN>
<!-- ======================= My Doc Start Here ========================== -->
<P>
<a href="http://camel.apache.org/">
Apache Camel</a>
is a routing and mediation engine which implements the 
<a href="http://www.enterpriseintegrationpatterns.com/toc.html">Enterprise Integration Patterns</a>.
But don't the words <em>Enterprise Integration</em> scare you off. 
Camel is designed to be really light weight and has a small footprint.
So it can be reused anywhere, whether in a servlet, in a Web services stack, inside a full ESB or a 
standalone messaging application.
</P>
<p>
Camel make it really simple to implement messaging application.
So there is not much reasons why you could not use it in non-enterprise application.
In fact, it is possible to use Camel as a tool, similar to the way you use scripting languages.
For example, you could fire up the <a href="http://camel.apache.org/web-console.html">Camel Web Console</a> and
define a <em>messaging application</em> without write a single line of code.
</p>
<P>
This article is a getting-start type of tutorial. As you might have been guessed, I'm going to use
Groovy as the programming language. And the programs in this article are intend to be ran with Groovysh,
the <a href="http://groovy.codehaus.org/Groovy+Shell">Groovy Shell</a>. Reasons:
<ul>
<li>
Groovy is concise, expressive and have less noice than Java. All programs in this article are just a couple dozen lines long
and should be real easy to follow along.
</li>
<li>
Using Groovysh allows the reader to interact with the application.
</li>
</ul>
</P>

<BLOCKQUOTE>
I'm a Linux guy and am conformtable with VIM and working in command line. So bare with me.
</BLOCKQUOTE>

<h2>Putting the pieces together</h2>
<P>
First, I'm going to write a simple program to make sure I'm able to talk to Camel in Groovy. 
I'm not using an IDE like Eclipse, not
creating a project, not going to use any build tools like Maven. Any text editor will be sufficient.
Save the following code to a file named <b>CamelDemo.groovy</b> (<a href="http://crank-on-struts.googlecode.com/svn/groovy-camel/src/KickCamel.groovy">source download</a>).
</P>

<pre name="code" class="java">
import groovy.grape.Grape
Grape.grab(group:"org.apache.camel", module:"camel-core", version:"2.0.0")

class MyRouteBuilder extends org.apache.camel.builder.RouteBuilder { 
  void configure() { 
    from("direct://foo").to("mock://result") 
  }
}

mrb = new MyRouteBuilder()
ctx = new org.apache.camel.impl.DefaultCamelContext()
ctx.addRoutes mrb
ctx.start()

p = ctx.createProducerTemplate()
p.sendBody "direct:foo", "Camel Ride for beginner"

e = ctx.getEndpoint("mock://result")
ex = e.exchanges.first()
println "INFO> ${ex}"
</pre>
<P>
This little program does a couple things:
<ul>
<li>
Import the <em>camel-core</em> jar using <em>Grape.grab()</em>
</li>
<li>
Define a our custom <code>RouteBuilder</code>, which define a simple route between 
a <em>direct:foo</em> and a <em>mock:result</em> enpoints. 
</li>
<li>
Instantiates the <em>CamelContext</em>, adds our custom <em>RouteBuilder</em> to it
and start Camel by <em>ctx.start()</em>.
</li>
<li>
Test the route by sending a message exchange using the <em>producerTemplate</em> obtained from
the <em>CamelContext</em>
</li>
<li>
Lookup the <em>mock:result</em> endpoint (<em>ctx.getEndpoint("mock:result")</em>) and dislay
the first <em>Exchange</em>, which should contain the message we just sent.
</li>
</ul>
</P>
<P>
Now start the groovysh in a command window and load the program:
</P>
<blockquote>
<pre>
$ groovysh
groovy:000> <b>load CamelDemo.groovy</b>
</pre>
</blockquote>
<P>
you should see a bunch of output and then the output from the script:
</P>
<blockquote>
<pre>
INFO> Exchange[Message: Camel Ride for beginner]
===> null
groovy:000>
</pre>
</blockquote>
<P>
At this point, you can interact with the program via <em>groovysh</em>. For example the following
show a few thing you can do. 
</P>
<blockquote>
<pre>
groovy:000> <b>ctx.routes</b>
===> [EventDrivenConsumerRoute[Endpoint[seda://foo] -> UnitOfWork(Channel[sendTo(Endpoint[mock://result])])]]
groovy:000> <b>ctx.components</b>
===> {mock=org.apache.camel.component.mock.MockComponent@14f2bd7, seda=org.apache.camel.component.seda.SedaComponent@c759f5}
groovy:000> <b>ctx.endpoints</b>
===> [Endpoint[seda://foo], Endpoint[mock://result]]
groovy:000> <b>ctx.endpoints[1].exchanges</b>
===> [Exchange[Message: Camel Ride for beginner]]
groovy:000> <b>ctx.endpoints[1].exchanges[0].in.body</b>
===> Camel Ride for beginner
groovy:000> <b>p.sendBody("seda:foo", "Camel Kicking")</b>
===> null
groovy:000> <b>e.exchanges</b>
===> [Exchange[Message: Camel Ride for beginner], Exchange[Message: Camel Kicking]]
</pre>
</blockquote>
<P>
This is it for our first Groovy/Camel program. For the curious, you can actually
modify the program and reload it without terminating and restarting <em>groovysh</em>.
</P>

<h2>Camel Stock Quote</h2>
<P>
This is a simple stock quote application. Initially, I planed to walk you thru the
development steps, from adding a simple bean as a <em>Processor</em> to transforming it
to a Multi-Channel, Multi-Data-Format service application. 
</P>
<P>
But after I've finished developing the program,
it turns out that it is too simple to justify for such elaboration. So to save your time and mine, I'm just
going to show you the final version right here. Take a look at it, and if you can understand what it does,
then may be you should skip the rest of this article :)
</P>
<P>
Save the following code to a file named <b>StockQuote.groovy</b> (<a href="http://crank-on-struts.googlecode.com/svn/groovy-camel/src/StockQuote.groovy">source download</a>).
</P>

<pre name="code" class="java">

import groovy.grape.Grape
Grape.grab(group:"org.apache.camel", module:"camel-core", version:"2.0.0")
Grape.grab(group:"org.apache.camel", module:"camel-jetty", version:"2.0.0")
Grape.grab(group:"org.apache.camel", module:"camel-freemarker", version:"2.0.0")

class QuoteServiceBean {
  public String usStock(String symbol) {
    "${symbol}: 123.50 US\$"
  }
  public String hkStock(String symbol) {
    "${symbol}: 90.55 HK\$"
  }
}

class MyRouteBuilder extends org.apache.camel.builder.RouteBuilder { 
  void configure() { 
    from("direct://quote").choice()
      .when(body().contains(".HK")).bean(QuoteServiceBean.class, "hkStock")
      .otherwise().bean(QuoteServiceBean.class, "usStock")
      .end().to("mock://result")
    from("direct://xmlquote").transform().xpath("//quote/@symbol", String.class).to("direct://quote")
	//curl -H "Content-Type: text/xml" http://localhost:8080/quote?symbol=IBM
    from('jetty:http://localhost:8080/quote').transform()
       .simple('&lt;quote symbol="${header.symbol}">&lt;/quote>').to("direct://xmlquote").choice()
           .when(header("Content-Type").isEqualTo("text/xml")).to("freemarker:xmlquote.ftl")
           .otherwise().to("freemarker:htmlquote.ftl")
         .end()
  }
}

ctx = new org.apache.camel.impl.DefaultCamelContext()
mrb = new MyRouteBuilder()
ctx.addRoutes mrb
ctx.start()
p = ctx.createProducerTemplate()

//p.sendBody("direct:quote", "00005.HK")
//p.sendBody("direct:xmlquote", "&lt;quote symbol='IBM'/>")
//p.sendBody("direct:xmlquote", "&lt;quote symbol='00005.HK'/>")

e = ctx.getEndpoint("mock://result")
//e.exchanges.each { ex ->
//  println "INFO> in.body='${ex.in.body}'"
//}
</pre>

<P>
OK, you are still here.
</P>
<P>
Let assumed that:
<ul>
<li>
We have two market data providers, one for U.S. market and the other for Hong Kong market.
</li>
<li>
An existing <b><em>QuoteServiceBean</em></b> class has been implemented as a POJO. It has two methods, 
<em>usStock()</em> and <em>hkStock()</em>. It is part of an <b>legacy</b> system, it works great, it hides 
the underlying details of interacting with the data providers. No one understand it and 
no one dare to modify it.
</li>
<li>
We would like utilizing the existing <b><em>QuoteServiceBean</em></b>
to provide a stock quote service that can be consume easily. i.e. Multi-Channel
and Multi-Data-Format.
</li>
</ul>
</P>

<h3>
Content Based Router and Message Translator
</h3>
<P></P>
<blockquote>
<pre name="code" class="java">
    from("direct://quote").choice()
      .when(body().contains(".HK")).bean(QuoteServiceBean.class, "hkStock")
      .otherwise().bean(QuoteServiceBean.class, "usStock")
      .end().to("mock://result")
</pre>
</blockquote>
<P>
The first route (start at line 17) represented by the <em>direct:quote</em> endpoint. It routes the message according
to the content of the body of the exchange, which assumed to contain the stock symbol. 
When the body of the exchange contains the string ".HK"
the <em>hkStock(String symbol)</em> of <em>QuoteServiceBean</em> is called, otherwise the 
<em>usStock(String symbol)</em> of <em>QuoteServiceBean</em> is called. 
Notice that the route DSL almost read like plain English!
</P>
<P>
Let us try it out. First start <em>groovysh</em>, load the program and send two messages to the
<em>direct:quote</em> endpoint:
</P>
<blockquote>
<pre>
jack@localhost tmp]$ <b>groovysh</b> 
Groovy Shell (1.6.6, JVM: 1.6.0_11)
groovy:000> <b>load StockQuote.groovy</b>
..............
groovy:000> <b>p.sendBody("direct:quote", "00001.HK")</b>
===> null
groovy:000> <b>e.exchanges.last()</b>
===> Exchange[Message: 00001.HK: 90.55 HK$]
groovy:000> <b>p.sendBody("direct:quote", "SUNW")</b>
===> null
groovy:000> <b>e.exchanges.last()</b>                
===> Exchange[Message: SUNW: 123.50 US$]
groovy:000>
</pre>
</blockquote>
<P>
That is it, our simple content-based router successfully routes request to the corresponding
processor methods.
</P>

<h3>XML Quote Request, message Transform</h3>
<P>
<blockquote>
<pre name="code" class="java">
    from("direct://xmlquote").transform().xpath("//quote/@symbol", String.class).to("direct://quote")
</pre>
</blockquote>
</P>
<P>
This next route simply accepts requests in XML, transforms the request and chains it to <em>direct://quote</em>.
With this, we've added the capability to accept requests in XML format!
</P>
<BLOCKQUOTE>
We are using <a href="http://camel.apache.org/xpath.html">XPath</a> here to expression our transform. Check out the hosts of 
<a href="http://camel.apache.org/expression.html">Expression Langauges</a> supported by Camel.
</BLOCKQUOTE>
<P>
Let us try it out:
</P>
<blockquote>
<pre>
groovy:000> <b>p.sendBody("direct:xmlquote", "&lt;quote symbol='GOOG'/&gt;")</b>
===> null
groovy:000> <b>e.exchanges.last()</b>
===> Exchange[Message: GOOG: 123.50 US$]
groovy:000>
</pre>
</blockquote>
<P></P>

<h3>Multi-Channel, Multi-Data-Format Provisioning</h3>
<P>
<blockquote>
<pre name="code" class="java">
Grape.grab(group:"org.apache.camel", module:"camel-jetty", version:"2.0.0")
Grape.grab(group:"org.apache.camel", module:"camel-freemarker", version:"2.0.0")
    // ........... lines removed for brevity .............
    from('jetty:http://localhost:8080/quote').transform()
       .simple('&lt;quote symbol="${header.symbol}">&lt;/quote>').to("direct://xmlquote").choice()
           .when(header("Content-Type").isEqualTo("text/xml")).to("freemarker:xmlquote.ftl")
           .otherwise().to("freemarker:htmlquote.ftl")
         .end()
</pre>
</blockquote>
</P>
<P>
Here we use the <a href="http://camel.apache.org/jetty.html">camel-jetty</a> to expose an endpoint 
<em>jetty:http://localhost:8080/quote</em> to 
our <em>quote service</em>. Note that <a href="http://camel.apache.org/jetty.html">camel-jetty</a>
is not part of <em>camel-core</em>.
That is why we have to <em>grab</em> it into our program.
</P>
<P>
The HTTP request is translate into XML using <a href="http://camel.apache.org/simple.html">simple expression</a>.
Note that the <em>camel-jetty</em> has kindly extracted the request parameters as well as the HTTP header and placed
them on the <a href="http://camel.apache.org/message.html">Message</a> header. So the request parameter <em>symbol</em>
is access as <em>${header.symbol}</em> in the expression.
</P>
<P>
Next we simply chain the message exchange to the <em>direct:xmlquote</em> endpoint.
</P>
<P>
The result from <em>direct:xmlquote</em> went thru another translation, which depends on the 
<em>content-type</em> of the orginating HTTP request. Here, I make use of the 
<a href="http://camel.apache.org/freemarker.html">camel-freemarker</a> to generate the desire output. 
So we need to create the two Freemarker templates:
<blockquote>
<b>htmlquote.ftl</b>
<pre>
&lt;html>
&lt;head>
&lt;/head>
&lt;body>
&lt;em>${body}&lt;/em>
&lt;/body>
&lt;/html>
</pre>
</blockquote>
<br/>
<blockquote>
<b>xmlquote.ftl</b>
<pre>
&lt;quote-result symbol='${headers.symbol}'>
${body}
&lt;/quote-result>
</pre>
</blockquote>
</P>
<P>
So let us see it in action, I'm going to use <em>curl</em> to make HTTP requests. Do this
on another command window:
</P>
<P>
<BLOCKQUOTE>
<PRE>
[jack@localhost tmp]$ <b>curl http://localhost:8080/quote?symbol=IBM</b>
&lt;html>
&lt;head>
&lt;/head>
&lt;body>
&lt;em>IBM: 123.50 US$&lt;/em>
&lt;/body>
&lt;/html>
[jack@localhost tmp]$ <b>curl http://localhost:8080/quote?symbol=00001.HK</b>
&lt;html>
&lt;head>
&lt;/head>
&lt;body>
&lt;em>00001.HK: 90.55 HK$&lt;/em>
&lt;/body>
&lt;/html>
[jack@localhost tmp]$ 
</PRE>
</BLOCKQUOTE>
</P>

<P>
And to request XML content:
</P>
<P>
<BLOCKQUOTE>
<PRE>
[jack@localhost tmp]$ <b>curl -H "Content-Type: text/xml" http://localhost:8080/quote?symbol=IBM</b>
&lt;quote-result symbol='IBM'>
IBM: 123.50 US$
&lt;/quote-result>
[jack@localhost tmp]$
</PRE>
</BLOCKQUOTE>
</P>
<P>
That's about it for our multi-channel/multi-data-format ser vice provision. 
</P>
<h2>Summary</h2>
<P>
In this tutorial, I hope to illustrate how Camel supports message passing paradigm style of application
development. Camel provides all sort of components to help you build processing pipelines. All you need
is to implement your business logic as simple POJOs and let Camel handles all the translating, routing,
filtering, spliting and forwarding for you.
</P>
<P>
Not shown in this tutorial is to consume external resources and services from with a route. No sweat, it 
is just as easy.
</P>
<P>
Camel integrates nicely with Spring as well as Guice, but work nicely on its own. It won't be in your way
if you don't need DI supports in your application. As they say: <b>Keep the simple easy</b>.
</P>
<P>
Camel works nicely in a JBI environment like ServiceMix and OpenESB. Camel is OSGI-ready and tracks newly deployed 
bundles for Route definitions at runtime. So you can gear it all to way up to be part of an enterprise SOA
infrastructure.
</P>
<P>
Disclaimer, I'm not an experienced Camel user and still learning. Thank you for staying up with me.
</P>
<!-- ========================== My Doc stop here ========================== -->

      <DIV class="field-label">Article Type:&nbsp;</DIV>
    <DIV class="field-items">
            <DIV class="field-item odd">
                    Opinion/Editorial        </DIV>
        </DIV>
</DIV>
<FORM action="./_files/Static Groovy and Concurrency  Type Inference in Action   Javalobby.html" accept-charset="UTF-8" method="post" id="fivestar-form-node-14831" class="fivestar-widget">
<DIV><DIV class="fivestar-form-vote-14831 clear-block"><INPUT type="hidden" name="content_type" id="edit-content-type-14831" value="node">
<INPUT type="hidden" name="content_id" id="edit-content-id-14831" value="14831">
<DIV class="fivestar-form-item  fivestar-average-text fivestar-user-stars fivestar-labels-hover fivestar-processed"><DIV class="form-item" id="edit-vote-0-wrapper">
 <LABEL for="edit-vote-0">Your rating: </LABEL>
 <INPUT type="hidden" name="vote_count" id="edit-vote-count-0" value="7">
<INPUT type="hidden" name="vote_average" id="edit-vote-average-0" value="94.2857">
<INPUT type="hidden" name="auto_submit_path" id="edit-auto-submit-path-0" value="/fivestar/vote/node/14831/vote" class="fivestar-path">
<SELECT name="vote" class="form-select" id="edit-vote-0" style="display: none; "><OPTION value="-">Select rating</OPTION><OPTION value="20">Poor</OPTION><OPTION value="40">Okay</OPTION><OPTION value="60">Good</OPTION><OPTION value="80">Great</OPTION><OPTION value="100">Awesome</OPTION></SELECT><DIV class="fivestar-widget clear-block fivestar-widget-5"><DIV class="star star-1 star-odd star-first"><A href="http://java.dzone.com/articles/static-groovy-and-concurrency-3#20" title="Poor">Poor</A></DIV><DIV class="star star-2 star-even"><A href="http://java.dzone.com/articles/static-groovy-and-concurrency-3#40" title="Okay">Okay</A></DIV><DIV class="star star-3 star-odd"><A href="http://java.dzone.com/articles/static-groovy-and-concurrency-3#60" title="Good">Good</A></DIV><DIV class="star star-4 star-even"><A href="http://java.dzone.com/articles/static-groovy-and-concurrency-3#80" title="Great">Great</A></DIV><DIV class="star star-5 star-odd star-last"><A href="http://java.dzone.com/articles/static-groovy-and-concurrency-3#100" title="Awesome">Awesome</A></DIV></DIV><INPUT type="hidden" name="auto_submit_token" id="edit-auto-submit-token-0" value="7c7a665796a975dd7a5ea328f86acf4e" class="fivestar-token">

 <DIV class="description"><DIV class="fivestar-summary fivestar-summary-average-count fivestar-feedback-enabled"><SPAN class="average-rating">Average: <SPAN>4.7</SPAN></SPAN> <SPAN class="total-votes">(<SPAN>7</SPAN> votes)</SPAN></DIV></DIV>
</DIV>
</DIV><INPUT type="hidden" name="destination" id="edit-destination-14831" value="node/14831">
<INPUT type="submit" name="op" id="edit-fivestar-submit-14831" value="Rate" class="form-submit fivestar-submit" style="display: none; ">
<INPUT type="hidden" name="form_build_id" id="form-714064f8fb26fb23e353c2a073486d8e" value="form-714064f8fb26fb23e353c2a073486d8e">
<INPUT type="hidden" name="form_token" id="edit-fivestar-form-node-14831-form-token" value="c2d3844353ff53865a9ade735b5cb125">
<INPUT type="hidden" name="form_id" id="edit-fivestar-form-node-14831" value="fivestar_form_node_14831">
</DIV>
</DIV></FORM>
	
			<DIV style="clear: both;"></DIV>

    </DIV>
<UL class="links inline"><LI class="statistics_counter first"><SPAN>1706 reads</SPAN></LI>
<LI class="print_html last"><A href="http://java.dzone.com/print/14831" title="Display a printer-friendly version of this page." class="print-page" rel="nofollow">Printer-friendly version</A></LI>
</UL><P style="font-size: 11px; padding-left: 1em;" class="disclaimer"><EM>(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)</EM></P></DIV>
<DIV id="comments"><H2 class="comments">Comments</H2><A id="comment-21611"></A>
<DIV class="comment odd">
		
		  	   		<A href="http://java.dzone.com/users/ilyasergey"><IMG src="./_files/picture-539433.png" alt="" title="" class="avatar" width="48" height="48"></A> 
    <DIV class="comment-wrap">
      <DIV class="tl"><!-- --></DIV>  
	    	<H3>ilyasergey replied on Mon, 2009/11/30 - 3:23pm</H3>
  	   	
	<DIV class="comment-content">
		   <!--paging_filter-->Very nice. But I wonder what will hapen in the last given code example if one assigns a <EM>float </EM>value to the <STRONG>sum </STRONG>variable, which is, as you wrote, was casted implicitly to the type <STRONG>int</STRONG>? In a presence of type coercion it's allowed to instantiate a variable of float type with an integer value, but the code in your example augmented with such implicit type assignments seems to be erroneous.		       			<DIV class="actions"><UL class="links"><LI class="comment_reply first last"><A href="http://java.dzone.com/comment/reply/14831/21611">reply</A></LI>
</UL></DIV>
  				</DIV>
 </DIV>
</DIV><FORM action="./_files/Static Groovy and Concurrency  Type Inference in Action   Javalobby.html" accept-charset="UTF-8" method="post" id="comment-controls">
<DIV><DIV class="box">





</DIV>
</DIV>
</DIV></DIV>
		</DIV>
	</DIV></DIV>
	<!-- end of squeeze, center (main content) -->
						<DIV id="sidebar-right" class="sidebar">
					<DIV id="search_bar" style="margin-bottom: 0px; padding-bottom: 0;">
	<FORM action="./_files/Static Groovy and Concurrency  Type Inference in Action   Javalobby.html" accept-charset="UTF-8" method="post" id="search-block-form">
<DIV><DIV class="container-inline">
  <DIV class="form-item" id="edit-search-block-form-1-wrapper">
 <LABEL for="edit-search-block-form-1">Search this site: </LABEL>
 <INPUT type="text" maxlength="128" name="search_block_form" id="edit-search-block-form-1" size="15" value="" title="Enter the terms you wish to search for." class="form-text">
</DIV>
<INPUT type="submit" name="op" id="edit-submit-3" value="Search" class="form-submit">
<INPUT type="hidden" name="form_build_id" id="form-374c8cd5d03197c12d956c47dddd3321" value="form-374c8cd5d03197c12d956c47dddd3321">
<INPUT type="hidden" name="form_token" id="edit-search-block-form-form-token" value="30e2aeddf3d403932a57295ad8d9a888">
<INPUT type="hidden" name="form_id" id="edit-search-block-form" value="search_block_form">
</DIV>

</DIV></FORM>
	
</DIV>
							<DIV id="feedLinks">		
													<A href="http://feeds.dzone.com/javalobby/frontpage"><IMG src="./_files/feed-icon-24x24.gif" style="border:0pt none; vertical-align:bottom;padding-right: 6px;">
							<IMG src="./_files/frontpage" style="border:0pt none; vertical-align:bottom;" alt="" height="26" width="88"></A>
											</DIV>
										<DIV id="mh_rectangle">
			<!-- BEGIN ADVERTPRO ADVANCED CODE BLOCK -->
			<SCRIPT language="JavaScript" type="text/javascript">
<!--
document.write('<SCR'+'IPT src="http://avpa.dzone.com/servlet/view/banner/javascript/zone?zid=93&keywords=java.dzone.com&pid=0&random='+Math.floor(89999999*Math.random()+10000000)+'&millis='+new Date().getTime()+'" language="JavaScript" type="text/javascript"></SCR'+'IPT>');
//-->
</SCRIPT><SCRIPT src="./_files/zone(1)" language="JavaScript" type="text/javascript"></SCRIPT>
<IFRAME src="./_files/B4098466.html" width="300" height="250" marginwidth="0" marginheight="0" hspace="0" vspace="0" frameborder="0" scrolling="no" bordercolor="#000000">
&lt;script language="JavaScript1.1" src="http://ad.doubleclick.net/adj/N4270.Dzone/B4098466.14;abr=!ie;sz=300x250;ord=20091202021617?"&gt;
&lt;/script&gt;
&lt;noscript&gt;
&lt;a href="http://ad.doubleclick.net/jump/N4270.Dzone/B4098466.14;abr=!ie4;abr=!ie5;sz=300x250;ord=20091202021617?"&gt;
&lt;img src="http://ad.doubleclick.net/ad/N4270.Dzone/B4098466.14;abr=!ie4;abr=!ie5;sz=300x250;ord=20091202021617?" border="0" width="300" height="250" alt="" CLICK HERE""&gt;&lt;/a&gt;
&lt;/noscript&gt;
</IFRAME>

			<NOSCRIPT></NOSCRIPT>
			<!-- END ADVERT PRO ADVANCED CODE BLOCK -->
		</DIV>
														<DIV id="block-dzone_extprofile-0" class="block block-dzone_extprofile">
  <H2>About the author</H2>

  <DIV class="content">
    <DIV class="author_info"><DIV class="node_author_pic" style="float: left;"><IMG src="./_files/picture-188481.jpg" alt="" title="" width="90" height="90"></DIV><DIV class="node_author_fields"><P><STRONG>First Name</STRONG>: Alex</P><P><STRONG>Last Name</STRONG>: Tkachman</P><P><B></B></P><P><STRONG>Posts:</STRONG> 3</P><P><STRONG>Joined:</STRONG> 11/15/2005</P><P><A href="http://java.dzone.com/users/alext">View full user profile</A></P></DIV></DIV><DIV style="clear: both;"></DIV>  </DIV>
</DIV>
<DIV id="block-block-5" class="block block-block">

  <DIV class="content">
    <DIV id="sidebar_features"><H2 class="header">Spotlight Features</H2>					  	<DIV>
	  		<A href="http://java.dzone.com/click/14783/1"><IMG src="./_files/jboss-savara.png" alt="" title="" class="node_author_pic" width="80" height="60"></A>
	  		<H2><A href="http://java.dzone.com/click/14783/1">Q&amp;A on SAVARA</A></H2>
	  		<P>We spoke with Gary Brown and Steve Ross-Talbot to get their ideas about architectural agility and how savara fits in.</P>	
	  	</DIV>
	  	<DIV>
	  		<A href="http://java.dzone.com/click/14679/1"><IMG src="./_files/infinispan_180x135.png" alt="" title="" class="node_author_pic" width="80" height="60"></A>
	  		<H2><A href="http://java.dzone.com/click/14679/1">Introducing Infinispan: Part I</A></H2>
	  		<P>Part I provides an overview of the capabilities of Infinispan, including usage examples and a tour of the API's.</P>	
	  	</DIV>
	  	<DIV>
	  		<A href="http://java.dzone.com/click/14505/1"><IMG src="./_files/benforta-podcast.png" alt="" title="" class="node_author_pic" width="80" height="60"></A>
	  		<H2><A href="http://java.dzone.com/click/14505/1">ColdFusion Trends with Ben Forta</A></H2>
	  		<P>ColdFusion guru Ben Forta discusses the state of ColdFusion, CF adoption
trends, and the future of the platform.</P>	
	  	</DIV>
</DIV>  </DIV>
</DIV>
<DIV id="block-block-3" class="block block-block">

  <DIV class="content">
    <UL class="sidebarlinks"><LI><H2>Popular at DZone</H2></LI><LI><A href="http://www.dzone.com/links/grailscertificationcom_is_online.html">GrailsCertification.com is online!</A></LI>
			<LI><A href="http://www.dzone.com/links/how_to_split_an_application_into_modules.html">How to Split an Application into Modules?</A></LI>
			<LI><A href="http://www.dzone.com/links/more_about_faster_java_coding_in_eclipse_galileo.html">More about faster Java coding in Eclipse Galileo</A></LI>
			<LI><A href="http://www.dzone.com/links/how_to_combine_rest_services_with_ejb_31.html">How to Combine REST Services with EJB 3.1</A></LI>
			<LI><A href="http://www.dzone.com/links/world_of_warcraft_on_the_netbeans_platform.html">World of Warcraft on the NetBeans Platform</A></LI>
			<LI><A href="http://www.dzone.com/links/content_based_routing_in_jbossesb_just_got_easier.html">Content Based Routing in JBossESB Just Got Easier</A></LI>
			<LI><A href="http://www.dzone.com/links/extension_methods_vs_method_currying_2.html">Extension methods vs. method currying</A></LI>
			<LI><A href="http://www.dzone.com/links/dzone_daily_dose_2009121.html">DZone Daily Dose - 2009/12/1</A></LI>
			<LI><A href="http://www.dzone.com/links/interview_keeping_track_of_deployed_artifacts_ove.html">Interview: Keeping Track of Deployed Artifacts Over Time</A></LI>
			<LI><A href="http://www.dzone.com/links/how_to_detect_os_in_java.html">How to detect OS in Java</A></LI>
			<LI><A class="moredz" href="http://www.dzone.com/">See more popular at DZone</A></LI><LI><A class="rss" href="http://feeds.dzone.com/dzone/frontpage">Subscribe to the RSS feed</A></LI></UL>  </DIV>
</DIV>
<DIV id="block-user-1" class="block block-user">
  <H2>jack_hung</H2>

  <DIV class="content">
    <UL class="menu"><LI class="leaf first"><A href="http://java.dzone.com/users/jackhung-0">My account</A></LI>
<LI class="collapsed activemenu-processed"><A href="http://java.dzone.com/node/add">Create content</A></LI>
<LI class="leaf"><A href="http://java.dzone.com/tracker">Recent posts</A></LI>
<LI class="leaf last"><A href="http://java.dzone.com/logout">Log out</A></LI>
</UL>  </DIV>
</DIV>
								</DIV>
		<!-- end of right sidebar -->
			
	<DIV id="footer"><DIV id="legal"><A href="http://java.dzone.com/page/tos">Terms of Service</A> - <A href="http://java.dzone.com/page/privacy">Privacy</A> - © 1997-2009, DZone, Inc.</DIV>
	</DIV>
	<!-- end of footer -->

</DIV><!-- end of container -->
</DIV><!-- end of wrapper -->
<SCRIPT type="text/javascript" src="./_files/f98b64cb41987937d65b0bc47af83889.js"></SCRIPT>
<SCRIPT type="text/javascript">
<!--//--><![CDATA[//><!--
jQuery.extend(Drupal.settings, { "basePath": "/", "fivestar": { "titleUser": "Your rating: ", "titleAverage": "Average: ", "feedbackSavingVote": "Saving your vote...", "feedbackVoteSaved": "Your vote has been saved.", "feedbackDeletingVote": "Deleting your vote...", "feedbackVoteDeleted": "Your vote has been deleted." }, "jstools": { "cleanurls": true, "basePath": "/" }, "activemenu": { "#block-book-0": "activemenu/book", "#block-menu-devel": "activemenu/menu", "#block-menu-menu-library-navigat": "activemenu/menu", "#block-menu-primary-links": "activemenu/menu", "#block-menu-secondary-links": "activemenu/menu", "#block-menu-menu-sections": "activemenu/menu", "#block-menu-menu-zones": "activemenu/menu", "#block-user-1": "activemenu/menu" }, "wysiwyg": { "configs": { "tinymce": { "format1": { "button_tile_map": true, "document_base_url": "/", "entity_encoding": "raw", "mode": "none", "plugins": "table,dwcode", "relative_urls": false, "theme": "advanced", "width": "100%", "apply_source_formatting": 0, "convert_fonts_to_spans": 1, "language": "en", "paste_auto_cleanup_on_paste": 0, "preformatted": 0, "remove_linebreaks": 0, "verify_html": 1, "content_css": "/sites/all/themes/dzone/css/editor_content.css", "extended_valid_elements": "font[face|size|color|style],span[class|align|style]", "theme_advanced_resize_horizontal": false, "theme_advanced_resizing_use_cookie": false, "theme_advanced_path_location": "bottom", "theme_advanced_resizing": 1, "theme_advanced_toolbar_location": "top", "theme_advanced_toolbar_align": "left", "theme_advanced_blockformats": "p,blockquote,address,pre,h1,h2,h3,h4,h5,h6", "theme_advanced_buttons1": "bold,italic,underline,strikethrough,justifycenter,bullist,numlist,undo,redo,link,unlink,image,cleanup,forecolor,code,cut,copy,paste,removeformat,help,formatselect,tablecontrols,dwcode", "theme_advanced_buttons2": "", "theme_advanced_buttons3": "" } } }, "showToggle": 1, "editorBasePath": "/sites/all/modules/wysiwyg/tinymce/jscripts/tiny_mce", "execMode": "", "disable": "Disable rich-text", "enable": "Enable rich-text", "plugins": { "tinymce": [  ] } } });
//--><!]]>
</SCRIPT>
<SCRIPT type="text/javascript"> 
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.config.taName = "pre";
    SyntaxHighlighter.config.clipboardSwf = '/sites/all/themes/dzone/scripts/syntaxHighlighter/clipboard.swf';
    SyntaxHighlighter.all();
    dp.SyntaxHighlighter.HighlightAll('code');
</SCRIPT>

<SCRIPT type="text/javascript" src="./_files/008739bfd7f2c3ffe012f17fdcedb765.js"></SCRIPT><SCRIPT language="javascript" type="text/javascript" src="./_files/editor_template.js"></SCRIPT><SCRIPT language="javascript" type="text/javascript" src="./_files/en.js"></SCRIPT><SCRIPT language="javascript" type="text/javascript" src="./_files/en(1).js"></SCRIPT><LINK href="./_files/editor_ui.css" rel="stylesheet" type="text/css"><SCRIPT language="javascript" type="text/javascript" src="./_files/editor_plugin.js"></SCRIPT><SCRIPT language="javascript" type="text/javascript" src="./_files/en(2).js"></SCRIPT><SCRIPT language="javascript" type="text/javascript" src="./_files/editor_plugin(1).js"></SCRIPT><SCRIPT language="javascript" type="text/javascript" src="./_files/en(3).js"></SCRIPT>
	<SCRIPT type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</SCRIPT><SCRIPT src="./_files/ga.js" type="text/javascript"></SCRIPT>

<SCRIPT type="text/javascript">
var pageTracker = _gat._getTracker("UA-410289-1");
pageTracker._setDomainName(".dzone.com");
pageTracker._initData();
pageTracker._trackPageview();
</SCRIPT>
 
<!-- Start Quantcast tag -->
<SCRIPT type="text/javascript">
_qoptions={
qacct:"p-ebK_XdQH1HeLo"
};
</SCRIPT>
<SCRIPT type="text/javascript" src="./_files/quant.js"></SCRIPT>
<NOSCRIPT></NOSCRIPT>
<!-- End Quantcast tag -->
<SCRIPT type="text/javascript" language="JavaScript" src="./_files/atrk.js"></SCRIPT>
<SCRIPT type="text/javascript" language="JavaScript">_atrk_opts = {
atrk_acct: "2Zc291a0g0y12X" }; atrk ();</SCRIPT>
<NOSCRIPT></NOSCRIPT>

</BODY></HTML>
